import json
from flask import request, jsonify, current_app
from flasgger import swag_from
from flask_jwt_extended import jwt_required
from app import db
from app.models.venue import Venue, VenueTimeSlot
from app.models.activity import Activity
from app.api.v1 import api_v1
from app.utils.decorators import permission_required
from app.api.v1.docs.admin_docs import (
    ADMIN_GET_VENUES_DOC, ADMIN_CREATE_VENUE_DOC, ADMIN_UPDATE_VENUE_DOC,
    ADMIN_DELETE_VENUE_DOC, ADMIN_GET_TIME_SLOTS_DOC, ADMIN_CREATE_TIME_SLOT_DOC,
    ADMIN_UPDATE_TIME_SLOT_DOC, ADMIN_DELETE_TIME_SLOT_DOC
)
from app.utils.venue_validator import VenueValidator
from werkzeug.utils import secure_filename
import os
from datetime import datetime

@api_v1.route('/admin/venues', methods=['GET'])
@swag_from(ADMIN_GET_VENUES_DOC)
@jwt_required()
def admin_get_venues():
    """管理员获取场馆列表"""
    # 调试信息
    current_app.logger.debug(f"请求头: {request.headers}")
    current_app.logger.debug(f"Authorization: {request.headers.get('Authorization')}")
    
    # 获取查询参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('perPage', 10, type=int)
    venue_type = request.args.get('type')
    location = request.args.get('location')
    keyword = request.args.get('keyword')
    status = request.args.get('status')
    
    # 构建查询
    query = Venue.query.filter_by(is_deleted=False)
    
    # 应用筛选条件
    if venue_type:
        query = query.filter_by(type=venue_type)
    if location:
        query = query.filter_by(location=location)
    if keyword:
        query = query.filter(Venue.name.like(f'%{keyword}%'))
    if status is not None:
        try:
            status_int = int(status)
            query = query.filter_by(status=status_int)
        except ValueError:
            pass
    
    # 分页查询
    pagination = query.order_by(Venue.id.desc()).paginate(page=page, per_page=per_page)
    venues = pagination.items
    
    # 构建响应
    return jsonify({
        'code': 200,
        'message': '获取成功',
        'data': {
            'total': pagination.total,
            'pages': pagination.pages,
            'page': page,
            'perPage': per_page,
            'venues': [venue.to_dict() for venue in venues]
        }
    })


@api_v1.route('/admin/venues/<int:venue_id>', methods=['GET'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '获取场馆详情',
    'description': '获取指定场馆的详细信息，包括时间段信息\n\n**🔐 需要管理员Token认证**\n\n**接口状态：已测试✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        }
    ],
    'responses': {
        '200': {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '获取成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'id': {'type': 'integer', 'description': '场馆ID'},
                            'name': {'type': 'string', 'description': '场馆名称'},
                            'type': {'type': 'string', 'description': '场馆类型'},
                            'address': {'type': 'string', 'description': '详细地址'},
                            'location': {'type': 'string', 'description': '位置信息'},
                            'description': {'type': 'string', 'description': '场馆描述'},
                            'images': {'type': 'array', 'description': '场馆图片'},
                            'contact_phone': {'type': 'string', 'description': '联系电话'},
                            'open_time': {'type': 'string', 'description': '开放时间'},
                            'status': {'type': 'integer', 'description': '状态：1=开放 0=关闭'},
                            'time_slots': {'type': 'array', 'description': '时间段列表'}
                        }
                    }
                }
            }
        },
        '401': {'description': '未授权访问'},
        '404': {'description': '场馆不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
@permission_required('venue:view')
def admin_get_venue_detail(venue_id):
    """管理员获取场馆详情"""
    venue = Venue.query.get_or_404(venue_id)
    
    return jsonify({
        'code': 200,
        'message': '获取成功',
        'data': venue.to_dict(with_slots=True)
    })


@api_v1.route('/admin/venues', methods=['POST'])
@swag_from(ADMIN_CREATE_VENUE_DOC)
@jwt_required()
@permission_required('venue:create')
def admin_create_venue():
    """管理员创建场馆"""
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    # 使用验证器验证数据
    try:
        VenueValidator.validate_venue_data(data)
    except ValueError as e:
        return jsonify({'code': 400, 'message': str(e)}), 400
    
    # 检查场馆名称是否已存在
    if Venue.query.filter_by(name=data.get('name')).first():
        return jsonify({'code': 400, 'message': '场馆名称已存在'}), 400
    
    try:
        # 创建场馆
        venue = Venue(
            name=data.get('name'),
            type=data.get('type'),
            address=data.get('address'),
            location=data.get('location'),
            latitude=data.get('latitude'),
            longitude=data.get('longitude'),
            description=data.get('description', ''),
            images=json.dumps(data.get('images', [])),
            contact_phone=data.get('contactPhone', ''),
            open_time=data.get('openTime', ''),
            status=data.get('status', 1)
        )
        
        db.session.add(venue)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '创建成功',
            'data': venue.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建场馆异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/venues/<int:venue_id>', methods=['PUT'])
@swag_from(ADMIN_UPDATE_VENUE_DOC)
@jwt_required()
@permission_required('venue:update')
def admin_update_venue(venue_id):
    """管理员更新场馆信息"""
    venue = Venue.query.get_or_404(venue_id)
    
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    # 使用验证器验证更新数据
    try:
        VenueValidator.validate_venue_data(data, is_update=True)
    except ValueError as e:
        return jsonify({'code': 400, 'message': str(e)}), 400
    
    try:
        # 更新场馆信息
        if 'name' in data and data['name'] != venue.name:
            # 检查场馆名称是否已存在
            if Venue.query.filter_by(name=data['name']).first():
                return jsonify({'code': 400, 'message': '场馆名称已存在'}), 400
            venue.name = data['name']
        
        if 'type' in data:
            venue.type = data['type']
        if 'address' in data:
            venue.address = data['address']
        if 'location' in data:
            venue.location = data['location']
        if 'latitude' in data:
            venue.latitude = data['latitude']
        if 'longitude' in data:
            venue.longitude = data['longitude']
        if 'description' in data:
            venue.description = data['description']
        if 'images' in data:
            venue.images = json.dumps(data['images'])
        if 'contactPhone' in data:
            venue.contact_phone = data['contactPhone']
        elif 'contact_phone' in data:
            venue.contact_phone = data['contact_phone']
        if 'openTime' in data:
            venue.open_time = data['openTime']
        elif 'open_time' in data:
            venue.open_time = data['open_time']
        if 'status' in data:
            venue.status = data['status']
        
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '更新成功',
            'data': venue.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新场馆异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/venues/<int:venue_id>', methods=['DELETE'])
@swag_from(ADMIN_DELETE_VENUE_DOC)
@jwt_required()
@permission_required('venue:delete')
def admin_delete_venue(venue_id):
    """管理员删除场馆（逻辑删除）"""
    venue = Venue.query.get_or_404(venue_id)
    try:
        # 检查是否有关联的订单
        if venue.orders.count() > 0:
            return jsonify({'code': 400, 'message': '该场馆有关联订单，无法删除'}), 400
        # 逻辑删除
        venue.is_deleted = True
        db.session.commit()
        return jsonify({
            'code': 200,
            'message': '删除成功'
        })
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除场馆异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/venues/<int:venue_id>/time-slots', methods=['GET'])
@swag_from(ADMIN_GET_TIME_SLOTS_DOC)
@jwt_required()
@permission_required('venue:view')
def admin_get_venue_time_slots(venue_id):
    """管理员获取场馆时间段"""
    venue = Venue.query.get_or_404(venue_id)
    
    time_slots = VenueTimeSlot.query.filter_by(venue_id=venue_id).all()
    
    return jsonify({
        'code': 200,
        'message': '获取成功',
        'data': {
            'venue': venue.to_dict(),
            'timeSlots': [slot.to_dict() for slot in time_slots]
        }
    })


@api_v1.route('/admin/venues/<int:venue_id>/time-slots', methods=['POST'])
@swag_from(ADMIN_CREATE_TIME_SLOT_DOC)
@jwt_required()
@permission_required('venue:update')
def admin_create_time_slot(venue_id):
    """管理员创建场馆时间段"""
    venue = Venue.query.get_or_404(venue_id)
    
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    # 验证必要参数
    required_fields = ['dayOfWeek', 'startTime', 'endTime', 'price', 'capacity']
    for field in required_fields:
        if field not in data:
            return jsonify({'code': 400, 'message': f'缺少必要参数: {field}'}), 400
    
    day_of_week = data.get('dayOfWeek')
    start_time = data.get('startTime')
    end_time = data.get('endTime')
    price = data.get('price')
    capacity = data.get('capacity')
    status = data.get('status', 1)
    
    # 验证参数
    try:
        day_of_week = int(day_of_week)
        if day_of_week < 1 or day_of_week > 7:
            return jsonify({'code': 400, 'message': '星期几必须在1-7之间'}), 400
    except ValueError:
        return jsonify({'code': 400, 'message': '星期几必须是整数'}), 400
    
    try:
        price = float(price)
        if price < 0:
            return jsonify({'code': 400, 'message': '价格不能为负数'}), 400
    except ValueError:
        return jsonify({'code': 400, 'message': '价格必须是数字'}), 400
    
    try:
        capacity = int(capacity)
        if capacity < 1:
            return jsonify({'code': 400, 'message': '容量必须大于0'}), 400
    except ValueError:
        return jsonify({'code': 400, 'message': '容量必须是整数'}), 400
    
    # 检查时间格式
    if not (len(start_time) == 5 and start_time[2] == ':' and len(end_time) == 5 and end_time[2] == ':'):
        return jsonify({'code': 400, 'message': '时间格式错误，应为HH:MM格式'}), 400
    
    # 检查是否有重叠的时间段
    existing_slots = VenueTimeSlot.query.filter_by(venue_id=venue_id, day_of_week=day_of_week).all()
    for slot in existing_slots:
        if (start_time <= slot.start_time < end_time) or (start_time < slot.end_time <= end_time) or (slot.start_time <= start_time and slot.end_time >= end_time):
            return jsonify({'code': 400, 'message': '时间段重叠'}), 400
    
    try:
        # 创建时间段
        time_slot = VenueTimeSlot(
            venue_id=venue_id,
            day_of_week=day_of_week,
            start_time=start_time,
            end_time=end_time,
            price=price,
            capacity=capacity,
            status=status
        )
        
        db.session.add(time_slot)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '创建成功',
            'data': time_slot.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建时间段异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/time-slots/<int:time_slot_id>', methods=['PUT'])
@swag_from(ADMIN_UPDATE_TIME_SLOT_DOC)
@jwt_required()
@permission_required('venue:update')
def admin_update_time_slot(time_slot_id):
    """管理员更新时间段"""
    time_slot = VenueTimeSlot.query.get_or_404(time_slot_id)
    
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    try:
        # 更新时间段信息
        if 'dayOfWeek' in data:
            day_of_week = int(data['dayOfWeek'])
            if day_of_week < 1 or day_of_week > 7:
                return jsonify({'code': 400, 'message': '星期几必须在1-7之间'}), 400
            time_slot.day_of_week = day_of_week
        
        if 'startTime' in data:
            time_slot.start_time = data['startTime']
        
        if 'endTime' in data:
            time_slot.end_time = data['endTime']
        
        if 'price' in data:
            price = float(data['price'])
            if price < 0:
                return jsonify({'code': 400, 'message': '价格不能为负数'}), 400
            time_slot.price = price
        
        if 'capacity' in data:
            capacity = int(data['capacity'])
            if capacity < 1:
                return jsonify({'code': 400, 'message': '容量必须大于0'}), 400
            time_slot.capacity = capacity
        
        if 'status' in data:
            time_slot.status = data['status']
        
        # 检查是否有重叠的时间段
        if 'dayOfWeek' in data or 'startTime' in data or 'endTime' in data:
            existing_slots = VenueTimeSlot.query.filter(
                VenueTimeSlot.venue_id == time_slot.venue_id,
                VenueTimeSlot.day_of_week == time_slot.day_of_week,
                VenueTimeSlot.id != time_slot_id
            ).all()
            
            for slot in existing_slots:
                if (time_slot.start_time <= slot.start_time < time_slot.end_time) or \
                   (time_slot.start_time < slot.end_time <= time_slot.end_time) or \
                   (slot.start_time <= time_slot.start_time and slot.end_time >= time_slot.end_time):
                    return jsonify({'code': 400, 'message': '时间段重叠'}), 400
        
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '更新成功',
            'data': time_slot.to_dict()
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新时间段异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/time-slots/<int:time_slot_id>', methods=['DELETE'])
@swag_from(ADMIN_DELETE_TIME_SLOT_DOC)
@jwt_required()
@permission_required('venue:update')
def admin_delete_time_slot(time_slot_id):
    """管理员删除时间段"""
    time_slot = VenueTimeSlot.query.get_or_404(time_slot_id)
    
    try:
        # 检查是否有关联的订单
        if time_slot.orders:
            return jsonify({'code': 400, 'message': '该时间段有关联订单，无法删除'}), 400
        
        # 删除时间段
        db.session.delete(time_slot)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '删除成功'
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除时间段异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/upload', methods=['POST'])
@swag_from({
    'tags': ['文件管理'],
    'summary': '上传单个图片文件',
    'description': '上传场馆图片或其他图片文件\n\n**🔐 需要管理员Token认证**\n\n**接口状态：已测试✅**',
    'security': [{'Bearer': []}],
    'consumes': ['multipart/form-data'],
    'parameters': [
        {
            'name': 'file',
            'in': 'formData',
            'type': 'file',
            'required': True,
            'description': '要上传的图片文件（支持jpg, jpeg, png, gif格式，最大4MB）'
        }
    ],
    'responses': {
        '200': {
            'description': '上传成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '上传成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'filename': {'type': 'string', 'description': '文件名'},
                            'url': {'type': 'string', 'description': '文件访问URL'},
                            'size': {'type': 'integer', 'description': '文件大小（字节）'},
                            'upload_time': {'type': 'string', 'description': '上传时间'}
                        }
                    }
                }
            }
        },
        '400': {'description': '文件格式不支持或文件过大（超过4MB）'},
        '401': {'description': '未授权访问'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def admin_upload_image():
    """管理员上传场馆图片"""
    import uuid
    import time
    from datetime import datetime
    
    if 'file' not in request.files:
        return jsonify({'code': 400, 'message': '没有文件被上传'}), 400
    
    file = request.files['file']
    if file.filename == '':
        return jsonify({'code': 400, 'message': '未选择文件'}), 400
    
    # 检查文件类型
    allowed_extensions = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
    file_ext = file.filename.rsplit('.', 1)[1].lower() if '.' in file.filename else ''
    if file_ext not in allowed_extensions:
        return jsonify({'code': 400, 'message': '不支持的文件格式，仅支持: png, jpg, jpeg, gif, webp'}), 400
    
    # 检查文件大小 (限制为4MB)
    max_size = 4 * 1024 * 1024  # 4MB
    file.seek(0, 2)  # 移动到文件末尾
    file_size = file.tell()
    file.seek(0)  # 重置文件指针
    if file_size > max_size:
        return jsonify({'code': 400, 'message': '文件大小不能超过4MB'}), 400
    
    # 生成唯一文件名 - 使用时间戳和UUID避免重复
    timestamp = int(time.time())
    unique_id = str(uuid.uuid4()).replace('-', '')[:8]
    filename = f"venue_{timestamp}_{unique_id}.{file_ext}"
    
    # 场馆图片保存到venue子目录
    base_upload_folder = current_app.config.get('UPLOAD_FOLDER', 'uploads')
    upload_folder = os.path.join(base_upload_folder, 'venue')
    if not os.path.exists(upload_folder):
        os.makedirs(upload_folder)
    
    save_path = os.path.join(upload_folder, filename)
    
    try:
        file.save(save_path)
        # 构造图片URL - 只返回相对路径，不包含域名
        url = f'/uploads/venue/{filename}'
        
        return jsonify({
            'code': 200, 
            'message': '上传成功', 
            'data': {
                'url': url,
                'filename': filename,
                'original_name': file.filename,
                'size': os.path.getsize(save_path)
            }
        })
    except Exception as e:
        current_app.logger.error(f"图片上传失败: {str(e)}")
        return jsonify({'code': 500, 'message': '图片上传失败'}), 500


@api_v1.route('/admin/upload/batch', methods=['POST'])
@swag_from({
    'tags': ['文件管理'],
    'summary': '批量上传图片文件',
    'description': '批量上传多个场馆图片文件\n\n**🔐 需要管理员Token认证**\n\n**接口状态：已测试✅**',
    'security': [{'Bearer': []}],
    'consumes': ['multipart/form-data'],
    'parameters': [
        {
            'name': 'files',
            'in': 'formData',
            'type': 'array',
            'items': {'type': 'file'},
            'required': True,
            'description': '要批量上传的图片文件列表（支持jpg, jpeg, png, gif格式，每个文件最大4MB）'
        }
    ],
    'responses': {
        '200': {
            'description': '批量上传成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '批量上传成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'success_count': {'type': 'integer', 'description': '成功上传数量'},
                            'failed_count': {'type': 'integer', 'description': '失败数量'},
                            'files': {
                                'type': 'array',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'filename': {'type': 'string', 'description': '文件名'},
                                        'url': {'type': 'string', 'description': '文件访问URL'},
                                        'status': {'type': 'string', 'description': '上传状态'}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        '400': {'description': '文件格式不支持或请求无效'},
        '401': {'description': '未授权访问'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def admin_upload_images_batch():
    """管理员批量上传场馆图片"""
    import uuid
    import time
    from datetime import datetime
    
    # 获取所有上传的文件
    files = request.files.getlist('files')
    if not files or len(files) == 0:
        return jsonify({'code': 400, 'message': '没有文件被上传'}), 400
    
    allowed_extensions = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
    # 场馆图片保存到venue子目录
    base_upload_folder = current_app.config.get('UPLOAD_FOLDER', 'uploads')
    upload_folder = os.path.join(base_upload_folder, 'venue')
    if not os.path.exists(upload_folder):
        os.makedirs(upload_folder)
    
    uploaded_files = []
    failed_files = []
    
    for file in files:
        if file.filename == '':
            failed_files.append({
                'original_name': '未知文件',
                'error': '文件名为空'
            })
            continue
        
        # 检查文件类型
        file_ext = file.filename.rsplit('.', 1)[1].lower() if '.' in file.filename else ''
        if file_ext not in allowed_extensions:
            failed_files.append({
                'original_name': file.filename,
                'error': f'不支持的文件格式，仅支持: {", ".join(allowed_extensions)}'
            })
            continue
        
        # 检查文件大小
        max_size = 4 * 1024 * 1024  # 4MB
        file.seek(0, 2)
        file_size = file.tell()
        file.seek(0)
        if file_size > max_size:
            failed_files.append({
                'original_name': file.filename,
                'error': '文件大小不能超过4MB'
            })
            continue
        
        # 生成唯一文件名
        timestamp = int(time.time())
        unique_id = str(uuid.uuid4()).replace('-', '')[:8]
        filename = f"venue_{timestamp}_{unique_id}.{file_ext}"
        save_path = os.path.join(upload_folder, filename)
        
        try:
            file.save(save_path)
            # 构造图片URL - 只返回相对路径，不包含域名
            url = f'/uploads/venue/{filename}'
            
            uploaded_files.append({
                'url': url,
                'filename': filename,
                'original_name': file.filename,
                'size': os.path.getsize(save_path)
            })
        except Exception as e:
            current_app.logger.error(f"文件上传失败 {file.filename}: {str(e)}")
            failed_files.append({
                'original_name': file.filename,
                'error': f'上传失败: {str(e)}'
            })
    
    result = {
        'uploaded_count': len(uploaded_files),
        'failed_count': len(failed_files),
        'uploaded_files': uploaded_files
    }
    
    if failed_files:
        result['failed_files'] = failed_files
    
    if len(uploaded_files) > 0:
        return jsonify({
            'code': 200,
            'message': f'批量上传完成，成功{len(uploaded_files)}个，失败{len(failed_files)}个',
            'data': result
        })
    else:
        return jsonify({
            'code': 400,
            'message': '所有文件上传失败',
            'data': result
        }), 400


@api_v1.route('/admin/venue/<int:venue_id>/time-slots', methods=['GET', 'POST', 'PUT', 'DELETE'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '管理场馆时间段（统一接口）',
    'description': '管理指定场馆的时间段信息，支持查询、创建、更新、删除操作\n\n**🔐 需要管理员Token认证**\n\n**接口状态：已测试✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'method',
            'in': 'query',
            'type': 'string',
            'required': False,
            'description': '操作类型：get=查询 post=创建 put=更新 delete=删除'
        }
    ],
    'responses': {
        '200': {
            'description': '操作成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '操作成功'},
                    'data': {
                        'type': 'object',
                        'description': '返回数据，根据操作类型不同而变化'
                    }
                }
            }
        },
        '400': {'description': '请求参数错误'},
        '401': {'description': '未授权访问'},
        '404': {'description': '场馆或时间段不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def manage_venue_time_slots(venue_id):
    """管理场馆时间段价格"""
    if request.method == 'GET':
        # 获取场馆的所有时间段价格设置
        time_slots = VenueTimeSlot.query.filter_by(venue_id=venue_id).all()
        return jsonify({
            'code': 200,
            'data': [{
                'id': slot.id,
                'day_of_week': slot.day_of_week,
                'start_time': slot.start_time.strftime('%H:%M'),
                'end_time': slot.end_time.strftime('%H:%M'),
                'price': slot.price,
                'capacity': slot.capacity,
                'status': slot.status
            } for slot in time_slots]
        })
    
    elif request.method == 'POST':
        # 添加新的时间段价格设置
        data = request.get_json()
        new_slot = VenueTimeSlot(
            venue_id=venue_id,
            day_of_week=data['day_of_week'],
            start_time=datetime.strptime(data['start_time'], '%H:%M').time(),
            end_time=datetime.strptime(data['end_time'], '%H:%M').time(),
            price=data['price'],
            capacity=data['capacity'],
            status=data['status']
        )
        db.session.add(new_slot)
        db.session.commit()
        return jsonify({'code': 200, 'message': '时间段价格设置添加成功'})
    
    elif request.method == 'PUT':
        # 更新时间段价格设置
        data = request.get_json()
        slot = VenueTimeSlot.query.get(data['id'])
        if slot and slot.venue_id == venue_id:
            slot.day_of_week = data['day_of_week']
            slot.start_time = datetime.strptime(data['start_time'], '%H:%M').time()
            slot.end_time = datetime.strptime(data['end_time'], '%H:%M').time()
            slot.price = data['price']
            slot.capacity = data['capacity']
            slot.status = data['status']
            db.session.commit()
            return jsonify({'code': 200, 'message': '时间段价格设置更新成功'})
        return jsonify({'code': 404, 'message': '时间段价格设置不存在'})
    
    elif request.method == 'DELETE':
        # 删除时间段价格设置
        slot_id = request.args.get('id')
        slot = VenueTimeSlot.query.get(slot_id)
        if slot and slot.venue_id == venue_id:
            db.session.delete(slot)
            db.session.commit()
            return jsonify({'code': 200, 'message': '时间段价格设置删除成功'})
        return jsonify({'code': 404, 'message': '时间段价格设置不存在'})


@api_v1.route('/admin/venue/<int:venue_id>/bookings', methods=['GET'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '获取场馆预约记录',
    'description': '获取指定场馆的所有预约记录信息\n\n**🔐 需要管理员Token认证**\n\n**接口状态：已测试✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': '页码'
        },
        {
            'name': 'per_page',
            'in': 'query',
            'type': 'integer',
            'default': 10,
            'description': '每页数量'
        },
        {
            'name': 'status',
            'in': 'query',
            'type': 'integer',
            'description': '预约状态筛选：1=已预约 2=已签到 3=已取消'
        },
        {
            'name': 'date',
            'in': 'query',
            'type': 'string',
            'description': '预约日期筛选（YYYY-MM-DD）'
        }
    ],
    'responses': {
        '200': {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '获取成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'total': {'type': 'integer', 'description': '总记录数'},
                            'page': {'type': 'integer', 'description': '当前页码'},
                            'per_page': {'type': 'integer', 'description': '每页数量'},
                            'bookings': {
                                'type': 'array',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer', 'description': '预约ID'},
                                        'user_name': {'type': 'string', 'description': '用户姓名'},
                                        'phone': {'type': 'string', 'description': '联系电话'},
                                        'booking_date': {'type': 'string', 'description': '预约日期'},
                                        'time_slot': {'type': 'string', 'description': '时间段'},
                                        'status': {'type': 'integer', 'description': '状态'},
                                        'created_at': {'type': 'string', 'description': '创建时间'}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        '401': {'description': '未授权访问'},
        '404': {'description': '场馆不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def get_venue_bookings(venue_id):
    """获取场馆预订情况"""
    date = request.args.get('date')
    if not date:
        return jsonify({'code': 400, 'message': '请指定日期'})
    
    try:
        target_date = datetime.strptime(date, '%Y-%m-%d').date()
    except ValueError:
        return jsonify({'code': 400, 'message': '日期格式错误'})
    
    # 获取指定日期的所有预订
    from app.models.order import Order
    bookings = Order.query.filter(
        Order.venue_id == venue_id,
        Order.reservation_date == target_date
    ).all()
    
    # 获取场馆的所有时间段
    time_slots = VenueTimeSlot.query.filter_by(venue_id=venue_id).all()
    
    # 构建时间段预订情况
    booking_status = []
    for slot in time_slots:
        slot_bookings = [b for b in bookings if b.time_slot_id == slot.id]
        booking_status.append({
            'time_slot': {
                'id': slot.id,
                'day_of_week': slot.day_of_week,
                'start_time': slot.start_time,
                'end_time': slot.end_time,
                'price': float(slot.price),
                'capacity': slot.capacity
            },
            'is_booked': len(slot_bookings) > 0,
            'booked_count': sum(b.participant_count or 1 for b in slot_bookings),  # 按人数统计
            'remaining_capacity': slot.capacity - sum(b.participant_count or 1 for b in slot_bookings),
            'booking_info': [{
                'id': b.id,
                'order_no': b.order_no,
                'user_id': b.user_id,
                'user_name': b.user.nickname if hasattr(b, 'user') and b.user else '未知用户',
                'participant_count': b.participant_count or 1,
                'amount': float(b.amount),
                'status': b.status,
                'status_text': {0: '未支付', 1: '已支付', 2: '已取消', 3: '已完成', 4: '已退款'}.get(b.status, '未知'),
                'created_at': b.created_at.strftime('%Y-%m-%d %H:%M:%S') if b.created_at else None
            } for b in slot_bookings] if slot_bookings else None
        })
    
    return jsonify({
        'code': 200,
        'data': {
            'date': date,
            'booking_status': booking_status
        }
    })


@api_v1.route('/venues/<int:venue_id>/availability', methods=['GET'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '查询场馆时间段可用性（公开接口）',
    'description': '查询指定场馆在特定时间段内是否可用，无需登录\n\n**🔓 公开接口，无需Token认证**\n\n**接口状态：已修复✅**',
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'start_time',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': '开始时间（YYYY-MM-DD HH:MM:SS）'
        },
        {
            'name': 'end_time',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': '结束时间（YYYY-MM-DD HH:MM:SS）'
        }
    ],
    'responses': {
        '200': {
            'description': '查询成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '查询成功', 'description': '响应消息'},
                    'data': {
                        'type': 'object',
                        'description': '可用性信息',
                        'properties': {
                            'available': {'type': 'boolean', 'example': True, 'description': '该时间段是否可用'},
                            'conflicting_activities': {
                                'type': 'array',
                                'description': '冲突的活动列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer', 'example': 1, 'description': '活动ID'},
                                        'title': {'type': 'string', 'example': '篮球比赛', 'description': '活动标题'},
                                        'start_time': {'type': 'string', 'example': '2024-01-01 10:00:00', 'description': '活动开始时间'},
                                        'end_time': {'type': 'string', 'example': '2024-01-01 12:00:00', 'description': '活动结束时间'},
                                        'organizer': {'type': 'string', 'example': '张三', 'description': '组织者昵称'}
                                    }
                                }
                            },
                            'venue_capacity': {'type': 'integer', 'example': 100, 'description': '场馆最大容量'},
                            'venue_name': {'type': 'string', 'example': '篮球场A', 'description': '场馆名称'}
                        }
                    }
                }
            }
        },
        '400': {
            'description': '参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '参数错误', 'description': '错误信息'},
                    'data': {'type': 'null', 'description': '错误时为null'}
                }
            }
        },
        '404': {
            'description': '场馆不存在',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 404, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '场馆不存在', 'description': '错误信息'},
                    'data': {'type': 'null', 'description': '错误时为null'}
                }
            }
        },
        '500': {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '服务器内部错误', 'description': '错误信息'},
                    'data': {'type': 'null', 'description': '错误时为null'}
                }
            }
        }
    }
})
def check_venue_availability(venue_id):
    """查询场馆时间段可用性"""
    try:
        # 验证场馆是否存在
        venue = Venue.query.get_or_404(venue_id)
        
        # 获取查询参数
        start_time_str = request.args.get('start_time')
        end_time_str = request.args.get('end_time')
        
        if not start_time_str or not end_time_str:
            return jsonify({'code': 400, 'message': '缺少时间参数'}), 400
        
        # 解析时间
        try:
            start_time = datetime.strptime(start_time_str, '%Y-%m-%d %H:%M:%S')
            end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
        except ValueError:
            return jsonify({'code': 400, 'message': '时间格式错误，请使用 YYYY-MM-DD HH:MM:SS 格式'}), 400
        
        if start_time >= end_time:
            return jsonify({'code': 400, 'message': '开始时间必须早于结束时间'}), 400
        
        # 查询在此时间段内使用该场馆的活动
        conflicting_activities = Activity.query.filter(
            Activity.venue_id == venue_id,
            Activity.status.in_(['open', 'closed']),  # 排除已取消的活动
            db.or_(
                # 活动开始时间在查询时间段内
                db.and_(Activity.start_time >= start_time, Activity.start_time < end_time),
                # 活动结束时间在查询时间段内
                db.and_(Activity.end_time > start_time, Activity.end_time <= end_time),
                # 活动时间段包含查询时间段
                db.and_(Activity.start_time <= start_time, Activity.end_time >= end_time)
            )
        ).all()
        
        # 如果有冲突活动，则不可用
        available = len(conflicting_activities) == 0
        
        # 构造冲突活动信息
        conflicting_info = []
        for activity in conflicting_activities:
            # 安全地获取组织者昵称
            organizer_name = '未知'
            if activity.organizer:
                organizer_name = activity.organizer.nickname or '未命名'
            
            conflicting_info.append({
                'id': activity.id,
                'title': activity.title,
                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M:%S') if activity.start_time else None,
                'end_time': activity.end_time.strftime('%Y-%m-%d %H:%M:%S') if activity.end_time else None,
                'organizer': organizer_name
            })
        
        return jsonify({
            'code': 200,
            'message': '查询成功',
            'data': {
                'available': available,
                'conflicting_activities': conflicting_info,
                'venue_capacity': venue.max_capacity,
                'venue_name': venue.name
            }
        })
        
    except Exception as e:
        current_app.logger.error(f"查询场馆可用性失败: {str(e)}")
        return jsonify({'code': 500, 'message': '查询失败'}), 500


@api_v1.route('/admin/venues/<int:venue_id>/booking-statistics', methods=['GET'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '获取场馆预订统计数据',
    'description': '获取指定场馆的实时预订统计，包括每小时的预订情况\n\n**🔐 需要管理员Token认证**\n\n**接口状态：新增✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'date',
            'in': 'query',
            'type': 'string',
            'format': 'date',
            'description': '查询日期（YYYY-MM-DD），默认为今天'
        }
    ],
    'responses': {
        '200': {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '获取成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'venue_info': {
                                'type': 'object',
                                'properties': {
                                    'id': {'type': 'integer', 'description': '场馆ID'},
                                    'name': {'type': 'string', 'description': '场馆名称'},
                                    'max_capacity': {'type': 'integer', 'description': '最大容量'}
                                }
                            },
                            'statistics_date': {'type': 'string', 'description': '统计日期'},
                            'hourly_stats': {
                                'type': 'array',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'time_slot_id': {'type': 'integer', 'description': '时段ID'},
                                        'time_range': {'type': 'string', 'description': '时间范围'},
                                        'capacity': {'type': 'integer', 'description': '应该容纳人数'},
                                        'booked_count': {'type': 'integer', 'description': '已预订人数'},
                                        'attended_count': {'type': 'integer', 'description': '实际到场人数'},
                                        'available_spots': {'type': 'integer', 'description': '剩余名额'},
                                        'occupancy_rate': {'type': 'number', 'description': '预订率(%)'},
                                        'attendance_rate': {'type': 'number', 'description': '到场率(%)'},
                                        'per_person_price': {'type': 'number', 'description': '每人价格'}
                                    }
                                }
                            },
                            'daily_summary': {
                                'type': 'object',
                                'properties': {
                                    'total_capacity': {'type': 'integer', 'description': '日总容量'},
                                    'total_booked': {'type': 'integer', 'description': '日预订总数'},
                                    'total_attended': {'type': 'integer', 'description': '日到场总数'},
                                    'average_occupancy_rate': {'type': 'number', 'description': '平均预订率'},
                                    'average_attendance_rate': {'type': 'number', 'description': '平均到场率'}
                                }
                            }
                        }
                    }
                }
            }
        },
        '401': {'description': '未授权访问'},
        '404': {'description': '场馆不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def get_venue_booking_statistics(venue_id):
    """获取场馆预订统计数据"""
    from app.models.order import Order
    from app.models.checkin_record import CheckinRecord
    from datetime import date as date_type, datetime
    from sqlalchemy import func, and_
    
    # 获取场馆信息
    venue = Venue.query.get_or_404(venue_id)
    
    # 获取查询日期
    date_str = request.args.get('date')
    if date_str:
        try:
            query_date = datetime.strptime(date_str, '%Y-%m-%d').date()
        except ValueError:
            return jsonify({'code': 400, 'message': '日期格式错误，请使用YYYY-MM-DD格式'}), 400
    else:
        query_date = date_type.today()
    
    try:
        # 获取查询日期是星期几 (1-7 代表周一到周日)
        day_of_week = query_date.isoweekday()
        
        # 获取该场馆在指定星期几的时间段
        time_slots = VenueTimeSlot.query.filter_by(
            venue_id=venue_id, 
            day_of_week=day_of_week,
            status=1
        ).order_by(VenueTimeSlot.start_time).all()
        
        # 统计每个时间段的预订和到场数据
        hourly_stats = []
        total_capacity = 0
        total_booked = 0
        total_attended = 0
        
        for slot in time_slots:
            # 混合数据统计：活动参与 + 入场记录
            
            # 方案1：从入场记录表获取统计数据（如果有的话）
            checkin_records = CheckinRecord.query.filter(
                and_(
                    CheckinRecord.venue_id == venue_id,
                    CheckinRecord.time_slot_id == slot.id,
                    CheckinRecord.reservation_date == query_date
                )
            ).all()
            
            # 预订人数 = 入场记录的预约人数总和
            booked_count = sum(record.participant_count or 0 for record in checkin_records)
            
            # 到场人数 = 已入场状态的实际到场人数
            attended_count = sum(
                record.actual_participants or 0
                for record in checkin_records 
                if record.status in [1, 2]  # 1=已入场, 2=已出场
            )
            
            # 方案2：如果没有入场记录，则从活动参与数据统计
            if not checkin_records:
                from datetime import datetime, time
                slot_start = datetime.combine(query_date, time.fromisoformat(slot.start_time))
                slot_end = datetime.combine(query_date, time.fromisoformat(slot.end_time))
                
                # 查找该时间段内在该场馆的活动
                from app.models.activity import Activity, ActivityParticipant
                activities_in_slot = Activity.query.filter(
                    and_(
                        Activity.venue_id == venue_id,
                        Activity.status.in_(['open', 'closed']),
                        db.or_(
                            # 活动时间与时间段有重叠
                            and_(Activity.start_time >= slot_start, Activity.start_time < slot_end),
                            and_(Activity.end_time > slot_start, Activity.end_time <= slot_end),
                            and_(Activity.start_time <= slot_start, Activity.end_time >= slot_end)
                        )
                    )
                ).all()
                
                for activity in activities_in_slot:
                    # 预订人数 = 活动参与者数量
                    participants = ActivityParticipant.query.filter_by(
                        activity_id=activity.id, 
                        status='joined'
                    ).count()
                    booked_count += participants
                    
                    # 到场人数暂时等同于预订人数（没有入场记录时）
                    attended_count += participants
            
                capacity = slot.capacity
            available_spots = max(0, capacity - booked_count)
            occupancy_rate = round((booked_count / capacity * 100), 2) if capacity > 0 else 0
            attendance_rate = round((attended_count / booked_count * 100), 2) if booked_count > 0 else 0
            
            hourly_stats.append({
                'time_slot_id': slot.id,
                'time_range': f"{slot.start_time}-{slot.end_time}",
                'day_of_week': slot.day_of_week,
                'capacity': capacity,
                'booked_count': booked_count,
                'attended_count': attended_count,
                'available_spots': available_spots,
                'occupancy_rate': occupancy_rate,
                'attendance_rate': attendance_rate,
                'per_person_price': float(slot.per_person_price),
                'min_charge_count': slot.min_charge_count,
                'status': '爆满' if available_spots <= 0 else '可预订'
            })
            
            total_capacity += capacity
            total_booked += booked_count
            total_attended += attended_count
        
        # 计算日汇总数据
        average_occupancy_rate = round((total_booked / total_capacity * 100), 2) if total_capacity > 0 else 0
        average_attendance_rate = round((total_attended / total_booked * 100), 2) if total_booked > 0 else 0
        
        daily_summary = {
            'total_capacity': total_capacity,
            'total_booked': total_booked,
            'total_attended': total_attended,
            'available_total': total_capacity - total_booked,
            'average_occupancy_rate': average_occupancy_rate,
            'average_attendance_rate': average_attendance_rate
        }
        
        return jsonify({
            'code': 200,
            'message': '获取成功',
            'data': {
                'venue_info': {
                    'id': venue.id,
                    'name': venue.name,
                    'max_capacity': venue.max_capacity
                },
                'statistics_date': query_date.strftime('%Y-%m-%d'),
                'hourly_stats': hourly_stats,
                'daily_summary': daily_summary
            }
        })
        
    except Exception as e:
        current_app.logger.error(f"获取场馆预订统计异常: {str(e)}")
        import traceback
        traceback.print_exc()
        return jsonify({'code': 500, 'message': f'服务器错误: {str(e)}'}), 500


@api_v1.route('/admin/venues/<int:venue_id>/pricing', methods=['PUT'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '更新场馆按人头定价',
    'description': '更新场馆时间段的按人头定价信息\n\n**🔐 需要管理员Token认证**\n\n**接口状态：新增✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'properties': {
                    'time_slots': {
                        'type': 'array',
                        'items': {
                            'type': 'object',
                            'properties': {
                                'time_slot_id': {'type': 'integer', 'description': '时间段ID'},
                                'per_person_price': {'type': 'number', 'description': '每人价格'},
                                'min_charge_count': {'type': 'integer', 'description': '最小收费人数'},
                                'capacity': {'type': 'integer', 'description': '容量'}
                            },
                            'required': ['time_slot_id', 'per_person_price']
                        }
                    }
                },
                'required': ['time_slots']
            }
        }
    ],
    'responses': {
        '200': {
            'description': '更新成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '更新成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'updated_count': {'type': 'integer', 'description': '更新的时间段数量'},
                            'time_slots': {'type': 'array', 'description': '更新后的时间段信息'}
                        }
                    }
                }
            }
        },
        '400': {'description': '请求参数错误'},
        '401': {'description': '未授权访问'},
        '404': {'description': '场馆不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
@permission_required('venue:update')
def update_venue_pricing(venue_id):
    """更新场馆按人头定价"""
    venue = Venue.query.get_or_404(venue_id)
    
    data = request.get_json()
    if not data or 'time_slots' not in data:
        return jsonify({'code': 400, 'message': '缺少时间段定价数据'}), 400
    
    try:
        updated_slots = []
        updated_count = 0
        
        for slot_data in data['time_slots']:
            time_slot_id = slot_data.get('time_slot_id')
            per_person_price = slot_data.get('per_person_price')
            min_charge_count = slot_data.get('min_charge_count', 1)
            capacity = slot_data.get('capacity')
            
            # 验证必要参数
            if not time_slot_id or per_person_price is None:
                continue
                
            # 获取时间段
            time_slot = VenueTimeSlot.query.filter_by(id=time_slot_id, venue_id=venue_id).first()
            if not time_slot:
                continue
            
            # 更新定价信息
            time_slot.per_person_price = per_person_price
            time_slot.min_charge_count = min_charge_count
            
            if capacity is not None:
                time_slot.capacity = capacity
            
            time_slot.updated_at = datetime.now()
            
            updated_slots.append(time_slot.to_dict())
            updated_count += 1
        
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': f'成功更新{updated_count}个时间段',
            'data': {
                'updated_count': updated_count,
                'time_slots': updated_slots
            }
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新场馆定价异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500


@api_v1.route('/admin/venues/<int:venue_id>/checkin', methods=['POST'])
@swag_from({
    'tags': ['场馆管理'],
    'summary': '场馆签到管理',
    'description': '管理用户签到，更新实际到场人数\n\n**🔐 需要管理员Token认证**\n\n**接口状态：新增✅**',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'properties': {
                    'order_id': {'type': 'integer', 'description': '订单ID'},
                    'checkin_code': {'type': 'string', 'description': '签到码'},
                    'actual_attendance': {'type': 'integer', 'description': '实际到场人数'},
                    'checkin_status': {'type': 'integer', 'description': '签到状态：1-已签到，2-迟到，3-缺席'}
                },
                'required': ['order_id', 'actual_attendance', 'checkin_status']
            }
        }
    ],
    'responses': {
        '200': {
            'description': '签到成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '签到成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'order_id': {'type': 'integer', 'description': '订单ID'},
                            'actual_attendance': {'type': 'integer', 'description': '实际到场人数'},
                            'checkin_status': {'type': 'integer', 'description': '签到状态'},
                            'checkin_time': {'type': 'string', 'description': '签到时间'}
                        }
                    }
                }
            }
        },
        '400': {'description': '请求参数错误'},
        '401': {'description': '未授权访问'},
        '404': {'description': '订单不存在'},
        '500': {'description': '服务器内部错误'}
    }
})
@jwt_required()
def venue_checkin_management(venue_id):
    """场馆签到管理"""
    from app.models.order import Order
    
    data = request.get_json()
    if not data:
        return jsonify({'code': 400, 'message': '缺少请求数据'}), 400
    
    order_id = data.get('order_id')
    actual_attendance = data.get('actual_attendance')
    checkin_status = data.get('checkin_status')
    checkin_code = data.get('checkin_code')
    
    if not order_id or actual_attendance is None or checkin_status is None:
        return jsonify({'code': 400, 'message': '缺少必要参数'}), 400
    
    try:
        # 获取订单
        order = Order.query.filter_by(id=order_id, venue_id=venue_id).first()
        if not order:
            return jsonify({'code': 404, 'message': '订单不存在'}), 404
        
        # 验证签到码（如果提供）
        if checkin_code and order.checkin_code and checkin_code != order.checkin_code:
            return jsonify({'code': 400, 'message': '签到码错误'}), 400
        
        # 更新签到信息
        order.actual_attendance = actual_attendance
        order.checkin_status = checkin_status
        order.checkin_time = datetime.now()
        
        # 如果是完成签到，更新订单状态
        if checkin_status == 1:  # 已签到
            order.status = 3  # 已完成
        
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '签到成功',
            'data': {
                'order_id': order.id,
                'actual_attendance': order.actual_attendance,
                'checkin_status': order.checkin_status,
                'checkin_time': order.checkin_time.strftime('%Y-%m-%d %H:%M:%S')
            }
        })
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"场馆签到管理异常: {str(e)}")
        return jsonify({'code': 500, 'message': '服务器错误'}), 500 